use mac_address::mac_address_by_name;

use crate::error::{new_err, AppErr};


pub mod codec;
pub mod global;
pub mod path;

pub fn xor_sum(buf: &[u8]) -> u8 {
    let mut s = 0;
    for v in buf {
        s = s ^ *v;
    }
    s
}

pub fn new_buf(len: usize) -> Box<[u8]> {
    unsafe {
        let mut buf = Vec::with_capacity(len);
        buf.set_len(len);
        buf.into_boxed_slice()
    }
}

const HEX_LIST: [u8; 16] = [
    b'0', b'1', b'2', b'3',
    b'4', b'5', b'6', b'7',
    b'8', b'9', b'a', b'b',
    b'c', b'd', b'e', b'f',
];

pub fn to_hex(buf: &[u8]) -> String {
    let mut s = Vec::with_capacity(buf.len() * 2);
    for v in buf {
        let n = (*v) as usize;
        s.push( HEX_LIST[n >> 4] );
        s.push( HEX_LIST[n & 0x0F] );
    }
    unsafe { String::from_utf8_unchecked(s) }
}

pub fn to_hex_mac(buf: &[u8]) -> String {
    let mut s = Vec::with_capacity(buf.len() * 3 - 1);
    for (i, v) in buf.iter().enumerate() {
        let n = (*v) as usize;
        s.push( HEX_LIST[n >> 4] );
        s.push( HEX_LIST[n & 0x0F] );
        if i != (buf.len() - 1) {
            s.push(b':');
        }
    }
    unsafe { String::from_utf8_unchecked(s) }
}


pub fn get_mac_address(name: &str) -> Result<String, AppErr> {
    let mac = mac_address_by_name(name)
        .map_err(|_| new_err("mac addr err"))?
        .ok_or(new_err("no mac address"))?;
    return Ok( to_hex_mac(&mac.bytes()) );
}






